generic
   type Individu (<>) is private;
   with function "=" (i : Individu; j : Individu) return Boolean is <>;
   with function "<=" (i : Individu; j : Individu) return Boolean is <>;

   type Cercle (<>) is private;
   with function "=" (u : Cercle; v : Cercle) return Boolean is <>;
   with function "<=" (u : Cercle; v : Cercle) return Boolean is <>;

   type Texte (<>) is private;

   type Mur (<>) is private;
   with function Creer (i : Individu) return Mur is <>;
   with function Afficher(m : Mur; i : Individu; t : Texte; n : Natural) return Mur is <>;
   with function Est_defini(m : Mur; n : Natural) return Boolean is <>;
   with function Auteur(m : Mur; n : Natural) return Individu is <>;
package Sigma is
   type Modele is private;
   function Creer return Modele;
   function Inscrire ( c : Modele; i : Individu ) return Modele;
   function Bloquer ( c : Modele; i : Individu; j : Individu ) return Modele;
   function Debloquer ( c : Modele; i : Individu; j : Individu ) return Modele;
   function Ajouter_cercle ( c : Modele; i : Individu; u : Cercle ) return Modele;
   function Retirer_cercle ( c : Modele; i : Individu; u : Cercle ) return Modele;
   function Ajouter_membre ( c : Modele; u : Cercle; i : Individu; j : Individu ) return Modele;
   function Retirer_membre ( c : Modele; u : Cercle; i : Individu; j : Individu ) return Modele;
   function Poster ( c : Modele; i : Individu; u : Cercle; t : Texte ) return Modele;
   function Commenter ( c : Modele; i : Individu; n : Natural; t : Texte ) return Modele;
   function Est_inscrit ( c : Modele; i : Individu ) return Boolean;
   function Nombre_inscrits ( c : Modele ) return Natural;
   function Ieme_inscrit ( c : Modele; n : Natural ) return Individu;
   function Est_bloque ( c : Modele; i : Individu; j : Individu ) return Boolean;
   function Est_cercle_de ( c : Modele; i : Individu; u : Cercle) return Boolean;
   function Nombre_cercles ( c : Modele; i : Individu ) return Natural;
   function Ieme_cercle ( c : Modele; n : Natural; i : Individu ) return Cercle;
   function Est_membre_de ( c : Modele; u : Cercle; i : Individu; j : Individu ) return Boolean;
   function Nombre_membres ( c : Modele; i : Individu; u : Cercle) return Natural;
   function Ieme_membre ( c : Modele; n : Natural; i : Individu; u : Cercle ) return Individu;
   function Nombre_posts ( c : Modele ) return Natural;
   function Consulter ( c : Modele; i : Individu ) return Mur;
private
   type Modele_Builder is (Creer, Inscrire, Bloquer, Debloquer, Ajouter_cercle, Retirer_cercle, Ajouter_membre, Retirer_membre, Poster, Commenter);
   type Modele_Term (The_Builder : Modele_Builder);
   type Modele is access Modele_Term;
   type Modele_Term  (The_Builder : Modele_Builder) is record
      case The_Builder is
         when Creer => null;
         when Inscrire =>
            Inscrire_c : Modele;
            Inscrire_i : access Individu;
         when Bloquer =>
            Bloquer_c : Modele;
            Bloquer_i : access Individu;
            Bloquer_j : access Individu;
         when Debloquer =>
            Debloquer_c : Modele;
            Debloquer_i : access Individu;
            Debloquer_j : access Individu;
         when Ajouter_cercle =>
            Ajouter_cercle_c : Modele;
            Ajouter_cercle_i : access Individu;
            Ajouter_cercle_u : access Cercle;
         when Retirer_cercle =>
            Retirer_cercle_c : Modele;
            Retirer_cercle_i : access Individu;
            Retirer_cercle_u : access Cercle;
         when Ajouter_membre =>
            Ajouter_membre_c : Modele;
            Ajouter_membre_i : access Individu;
            Ajouter_membre_j : access Individu;
            Ajouter_membre_u : access Cercle;
         when Retirer_membre =>
            Retirer_membre_c : Modele;
            Retirer_membre_i : access Individu;
            Retirer_membre_j : access Individu;
            Retirer_membre_u : access Cercle;
         when Poster =>
            Poster_c : Modele;
            Poster_i : access Individu;
            Poster_u : access Cercle;
            Poster_t : access Texte;
         when Commenter =>
            Commenter_c : Modele;
            Commenter_i : access Individu;
            Commenter_n : Natural;
            Commenter_t : access Texte;

      end case;
   end record;
end Sigma;
